Boxenn::UseCase
中處理 validation?dry-monads 中有提供 validate 的功能,他的特色是不會中斷執行,而是等到所有 list 中的 validate 都執行完後再一次回傳所有的 failure。
# create_order.rb
class ValidOrder < Boxenn::UseCase
option :repo, default: -> { OrderRepository.new }
def steps(serial_number:)
order = retrieve_order(serial_number)
yield List::Validated[
valid_capacity(order),
valid_price(order),
].traverse.to_result
Success()
end
private
def retrieve_order(serial_number)
repo.find_by_identity(serial_number: serial_number)
end
def valid_capacity(order)
return Invalid(:capacity_error) if order.capacity < 0
Valid(Unit)
end
def valid_price(order)
return Invalid(:price_error) if order.price < 0
Valid(Unit)
end
end
result = ValidOrder.new.call(serial_number: 'ABC-1234567890')
# 成功
# => Success()
# 失敗
# => Failure(List[:capacity_error, :price_error])
這樣的特性用在參數的 validation 很方便,但會有一些問題產生:
List
物件(dry-monads 自定義的),而在未使用 List::Validated
的 use case 中不會特別在 failure 回傳 List
,使得介面不統一。List::Validated
當中的 method 全部都會執行,如果其中一個 method 執行失敗,後續仍會繼續執行,這與原本 use case 設計理念中的 sequential 性質有些違背。下篇會來聊聊 Boxenn::UseCase
目前的 error handling ,以及遇到的阻礙。